package com.caineng.zhaobiao.zbapi.service;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alicp.jetcache.anno.Cached;
import com.caineng.zhaobiao.zbapi.dao.CaiBaseUserDao;
import com.caineng.zhaobiao.zbapi.domain.CaiBaseUser;
import com.caineng.zhaobiao.zbapi.utils.AjaxResult;
import com.caineng.zhaobiao.zbapi.utils.MD5Util;
import com.caineng.zhaobiao.zbapi.utils.StringUtils;
import com.caineng.zhaobiao.zbapi.utils.ZhaoBiaoCommon;
import com.caineng.zhaobiao.zbapi.utils.genID.IDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Optional;

/**
 * 用户服务类
 * @author liandyao
 * @date 2022/7/22 14:22
 */
@Slf4j
@Service
public class UserService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private CaiBaseUserDao userDao;

    @Autowired
    private CainengApi cainengApi;


    /**
     * 登录,查询才能网的api,如果才能网api有值,则本地注册一个
     * @param username
     * @param password
     * @return
     */
    public AjaxResult login(String username, String password){
        //首先从本地数据库查询,然后从caineng接口查询,如果都没有,则提示登录失败
        CaiBaseUser user = new CaiBaseUser();
        user.setPhone(username);
        //user.setPassword(MD5Util.encode(password));
        Example<CaiBaseUser> ex = Example.of(user);
        Optional<CaiBaseUser> po = userDao.findOne(ex) ;
        CaiBaseUser userPo = po.orElse(null) ;

        if(userPo==null){


            /*
            JSONObject obj = null ;
            try {
                //去才能网接口查找
                obj = cainengApi.login(username, password);
            }catch(Exception e){
                //接口无法接通
                e.printStackTrace();
                //obj = new JSONObject();
                return AjaxResult.error("手机号还未注册");
            }

            //System.out.println(JSONUtil.toJsonStr(obj));
            // 返回成功,将用户加入到本地数据库
            if(StrUtil.equals("0",obj.getStr("code"))){
                //String userId = obj.getJSONObject("data").getStr("id");
                //JSONObject userJson = cainengApi.getUserInfo(userId);
                CaiBaseUser s = obj.getJSONObject("data").toBean(CaiBaseUser.class);
                //System.out.println(s);
                s.setPassword(MD5Util.encode(password));
                s.setCreateTime(DateUtil.now());
                userDao.insert(s);//保存到mongodb数据库

                return getAjaxResult(s);
            }*/
        }else{
            String passwd = userPo.getPassword();
            if(StrUtil.equals(MD5Util.encode(password),passwd)) {
                return getAjaxResult(userPo);
            }else{
                return AjaxResult.error("用户名或者密码错误");
            }
        }

        return AjaxResult.error("用户不存在");
    }

    /**
     * 用户token信息
     * @param s
     * @return
     */
    public AjaxResult getAjaxResult(CaiBaseUser s) {
        JSONObject result = new JSONObject();
        s.setPassword(null); //将密码设置为空,不显示在前端
        result.putOpt("userInfo", s);
        if(StrUtil.isBlank(s.getId())){
            return AjaxResult.error("登录失败");
        }
        //登录
        StpUtil.login(s.getId());
        log.info("==========登录id===========>"+s.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        JSONObject token = new JSONObject();
        token.putOpt("tokenName","cainengToken");
        token.putOpt("tokenValue",tokenInfo.getTokenValue());

        result.putOpt("tokenInfo",token);

        AjaxResult ajax = AjaxResult.success("登录成功",result);
        return ajax ;
    }





    /**
     * 根据userId查询用户
     * @param userId
     * @return
     */
    public CaiBaseUser findUserById(String userId) {
        log.info("根据ID查询人员....");
        CaiBaseUser user = new CaiBaseUser();
        user.setId(userId);
        Optional<CaiBaseUser> userPo = userDao.findOne(Example.of(user));
        return userPo.orElse(user);
    }

    /**
     * 注册账号
     * 并在才能网注册账号
     * @param user
     * @return
     */
    public AjaxResult register(CaiBaseUser user,String verifyCode) {
        String phone = user.getPhone();

        String password = user.getPassword();

        Assert.notNull(phone,"手机号码不能为空");
        Assert.notNull(password,"密码不能为空");


        if(!StringUtils.isTruePhone(phone)){
            return AjaxResult.error("不是正确的手机号码");
        }

        AjaxResult jsonSms = cainengApi.checkSMS(phone,verifyCode);
        CaiBaseUser po = null;
        if(AjaxResult.OK_CODE.equals(jsonSms.getCode())) {

            if(po==null) {
                po = new CaiBaseUser();
                po.setId(IDUtils.getID());
            }
            po.setPhone(user.getPhone());
            po.setEmail(user.getEmail());
            po.setShowName(user.getShowName());
            //密码没有传过来,这边再生成
            po.setPassword(MD5Util.encode(password));
            po.setCreateTime(DateUtil.now());
            log.info("用户信息:"+JSONUtil.toJsonStr(po));
            userDao.insert(po);//保存到mongodb数据库

            return getAjaxResult(po);

            /*

            //2022年11月2日注释掉,注册的同时,才能网也注册一份

            user.setId(IDUtils.getID());
            user.setPassword(MD5Util.encode(password));
            user.setCreateTime(DateUtil.now());
            userDao.insert(user);//保存到mongodb数据库
            return getAjaxResult(user);
            */

        }else{
            return AjaxResult.error(jsonSms.getMsg());
        }

    }

    /**
     * 根据手机号码查询用户,忽略删除标记
     * @param phone
     * @return
     */
    public CaiBaseUser findUserByPhoneIgnoreDelFlag(String phone) {
        Assert.notNull(phone,"手机号码不能为空");
        CaiBaseUser user = new CaiBaseUser();
        user.setPhone(phone);
        user.setDelFlag(null);
        Optional<CaiBaseUser> userPo = userDao.findOne(Example.of(user));
        if(userPo.isPresent()){
            return userPo.get();
        }else {
            return null ;
        }
    }

    /**
     * 根据手机号码查询用户,查询是否有效
     * @param phone
     * @return
     */
    public CaiBaseUser findUserByPhone(String phone,Integer delFlag) {
        Assert.notNull(phone,"手机号码不能为空");
        CaiBaseUser user = new CaiBaseUser();
        user.setPhone(phone);
        user.setDelFlag(delFlag);
        Optional<CaiBaseUser> userPo = userDao.findOne(Example.of(user));
        if(userPo.isPresent()){
            return userPo.get();
        }else {
            return null ;
        }
    }

    /**
     * 根据手机号码查询有效用户。已删除的用户查不到
     * @param phone
     * @return
     */
    public CaiBaseUser findUserByPhone(String phone) {

        return findUserByPhone(phone, ZhaoBiaoCommon.delFlag_NO);
    }

    /**
     * 根据邮箱查询人员
     * @param email
     * @return
     */
    public CaiBaseUser findUserByEmail(String email) {
        CaiBaseUser user = new CaiBaseUser();
        user.setEmail(email);
        Optional<CaiBaseUser> userPo = userDao.findOne(Example.of(user));
        if(userPo.isPresent()){
            return userPo.get();
        }else {
            return null ;
        }
    }

    /**
     * 根据微信的unionId查询人员
     * @param unionId
     * @return
     */
    public CaiBaseUser findUserByUnionid(String unionId) {
        CaiBaseUser user = new CaiBaseUser();
//        user.setUnionid(unionId);
//        Optional<CaiBaseUser> userPo = userDao.findOne(Example.of(user));
        user = mongoTemplate.findOne(Query.query(Criteria.where("unionid").is(unionId)),CaiBaseUser.class);
        return user ;
    }

    //expire 单位:秒

    /**
     * 使用缓存
     * @param userId
     * @return
     */
    @Cached(name="ZHAOBIAO:userCache:ById:", key="#userId", expire = 3600*24)
    public CaiBaseUser findUserByIdCache(String userId) {

        CaiBaseUser user = findUserById(userId);

        return user;
    }

    /**
     * 使用缓存 iosId
     * @param iosId
     * @return
     */
    @Cached(name="ZHAOBIAO:userCache:ByIOSId:", key="#iosId", expire = 3600*24)
    public CaiBaseUser findUserByIosIdCache(String iosId) {
        CaiBaseUser user   = mongoTemplate.findOne(Query.query(Criteria.where("iosId").is(iosId)),CaiBaseUser.class);
        return user;
    }
}
